﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ReportsController.cs" company="DissingNellemann">
//   
// All rights reserved </copyright>
// <summary>
//   The reports controller.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Website.Controllers
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Mvc;

    using Website.CRUDServices;
    using Website.Models;
    using Website.Models.Styling;
    using Website.Models.ViewModels;

    /// <summary>
    ///     The reports controller.
    /// </summary>
    [Authorize(Roles = "User, Admin")]
    public class ReportsController : BaseController
    {
        #region Public Methods and Operators
        /// <summary>
        ///     The index.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult Index()
        {
            this.Init("Reports");
            var submenuItems = new List<MenuItem>();
            var item = new MenuItem
            {
                ActionName = "BusinessDevelopmentSearch",
                ControllerName = "Reports",
                CurrentMenuSelectionName = "BusinessDevelopment",
                ImageName = "notepad",
                Title = "Forretnings-udvikling"
            };
            submenuItems.Add(item);

            var item2 = new MenuItem
            {
                ActionName = "MatchmakingSearch",
                ControllerName = "Reports",
                CurrentMenuSelectionName = "Matchmaking",
                ImageName = "notepad",
                Title = "Matchmaking"
            };
            submenuItems.Add(item2);

            var item3 = new MenuItem
            {
                ActionName = "NetworkingSearch",
                ControllerName = "Reports",
                CurrentMenuSelectionName = "Networking",
                ImageName = "notepad",
                Title = "Netværk"
            };
            submenuItems.Add(item3);

            var item4 = new MenuItem
            {
                ActionName = "ProjectsSearch",
                ControllerName = "Reports",
                CurrentMenuSelectionName = "Projects",
                ImageName = "notepad",
                Title = "Projekt"
            };
            submenuItems.Add(item4);

            var item5 = new MenuItem
            {
                ActionName = "ClusterSearch",
                ControllerName = "Reports",
                CurrentMenuSelectionName = "Clusters",
                ImageName = "notepad",
                Title = "Klynger"
            };
            submenuItems.Add(item5);
            var item6 = new MenuItem
            {
                ActionName = "NewsInformationSearch",
                ControllerName = "Reports",
                CurrentMenuSelectionName = "NewsInformation",
                ImageName = "notepad",
                Title = "Nyheds-information"
            };
            submenuItems.Add(item6);


            this.Session["SubMenuItems"] = submenuItems;

            return this.View();
        }

        /// <summary>
        ///     The business development search.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult BusinessDevelopmentSearch()
        {
            this.Session["CurrentSubMenuSelection"] = "BusinessDevelopment";
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["Locations"] = PrimitiveTypes.GetLocations();
            this.ViewData["Profiles"] = PrimitiveTypes.GetProfiles();
            this.ViewData["Topics"] = PrimitiveTypes.GetTopics();


            return this.View();
        }

        /// <summary>
        /// The business development search result.
        /// </summary>
        /// <param name="defaultFields">
        /// The default fields.
        /// </param>
        /// <param name="location">
        /// The location.
        /// </param>
        /// <param name="profiles">
        /// The profiles.
        /// </param>
        /// <param name="topics">
        /// The topics.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        [HttpPost]
        public ActionResult BusinessDevelopmentSearchResult(
            DefaultSearchFields defaultFields, 
            Guid? location,
            string remoteArea,
            string entrepeneur,
            List<Guid> profiles, 
            List<Guid> topics)
        {
            if (location.HasValue && location.Value == Guid.Empty)
            {
                location = null;
            }

            this.ViewData["CriteriaLocation"] = location;
            this.ViewData["CriteriaProfiles"] = profiles ?? new List<Guid>();
            this.ViewData["CriteriaTopics"] = topics ?? new List<Guid>();
            this.ViewData["DefaultFields"] = defaultFields;
            this.ViewData["Locations"] = PrimitiveTypes.GetLocations();

            ListView<Activity> view = null;
            List<TableViewHeaderItem> headerItems = BusinessDevelopmentController.GetHeaderItems();
            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    bool ent = entrepeneur == "true" ? true : false;
                    bool remote = remoteArea == "true" ? true : false;
                    var query = new ActivityQuery
                    {
                        HasBusinessDevelopment = true,
                        Settings = new SearchSettings(),
                        DefaultFields = defaultFields,
                        AtLocation = location,
                        ProfilesAreAtRemoteArea = remote,
                        ProfilesAreEntrepreneur=ent,
                        WithAttendees = (profiles ?? new List<Guid>()).ToArray(),
                        BAContainsTopics = (topics ?? new List<Guid>()).ToArray(),
                    };

                    var res = client.Query(query) as ActivityResult;
                    if (res != null)
                    {
                        view = new ListView<Activity>(res.List.ToList(), res.TotalRowCount, headerItems);

                        var uniqueAttendees = new List<Guid>();
                        foreach (var attendees in res.List.Select(x => x.Attendees))
                        {
                            uniqueAttendees.AddRange(attendees.ToList());
                        }

                        var uniqueTopics = new List<Guid>();
                        foreach (var topicList in res.List.Select(x => x.BDA.Topics))
                        {
                            uniqueTopics.AddRange(topicList.ToList());
                        }

                        this.ViewData["Profiles"] = PrimitiveTypes.GetProfilesWithIDs(uniqueAttendees);
                        this.ViewData["Topics"] = PrimitiveTypes.GetTopicsWithIDs(uniqueTopics);
                        this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
                    }
                });

            return View(view);
        }

        /// <summary>
        ///     The cluster search.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult ClusterSearch()
        {
            this.Session["CurrentSubMenuSelection"] = "Clusters";
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["ClusterMethodTypes"] = PrimitiveTypes.GetClusterMethodType();
            this.ViewData["ClusterStatusTypes"] = PrimitiveTypes.GetClusterStatusType();
            this.ViewData["Locations"] = PrimitiveTypes.GetLocations();
            this.ViewData["Profiles"] = PrimitiveTypes.GetProfiles();

            return View();
        }


        /// <summary>
        ///     The cluster search result.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult ClusterSearchResult(
            DefaultSearchFields defaultFields,
            Guid? location,
            string remoteArea,
            string entrepeneur,
            List<Guid> methodTypes, 
            List<Guid> profiles, 
            List<Guid> statusTypes)
        {
            this.ViewData["CriteriaLocation"] = location;
            this.ViewData["CriteriaMethodTypes"] = methodTypes ?? new List<Guid>();
            this.ViewData["CriteriaStatusTypes"] = statusTypes ?? new List<Guid>();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["ClusterMethodTypes"] = PrimitiveTypes.GetClusterMethodType();
            this.ViewData["ClusterStatusTypes"] = PrimitiveTypes.GetClusterStatusType();
            this.ViewData["Locations"] = PrimitiveTypes.GetLocations();
            this.ViewData["Profiles"] = PrimitiveTypes.GetProfiles();

            ListView<Cluster> view = null;
            List<TableViewHeaderItem> headerItems = ClusterController.GetHeaderItems();
            CRUDServiceProvider.WithCRUDService(client =>
            {
                bool ent = entrepeneur == "true" ? true : false;
                bool remote = remoteArea == "true" ? true : false;
                var query = new ClusterQuery()
                {
                    ProfilesAreAtRemoteArea = remote,
                    ProfilesAreEntrepreneur = ent,
                    AtLocation = location,
                    Profiles = (profiles ?? new List<Guid>()).ToArray(),
                    MethodTypes = (methodTypes ?? new List<Guid>()).ToArray(),
                    StatusTypes = (statusTypes ?? new List<Guid>()).ToArray(),
                    DefaultFields = defaultFields,
                    Settings = new SearchSettings()
                };
                var res = client.Query(query) as ClusterResult;
                if (res != null)
                {
                    view = new ListView<Cluster>(res.List.ToList(), res.TotalRowCount, headerItems);
                    var uniqueClusterMethods = new List<Guid>();
                    foreach (var methods in res.List.Select(x => x.Methods))
                    {
                        uniqueClusterMethods.AddRange(methods.ToList());
                    }

                    var uniqueClusterStatuses = new List<Guid>();
                    foreach (var statuses in res.List.Select(x => x.Statuses))
                    {
                        uniqueClusterStatuses.AddRange(statuses.ToList());
                    }

                    this.ViewData["ClusterMethods"] =
                        PrimitiveTypes.GetClusterMethodsWithIDs(uniqueClusterMethods.Distinct());
                    this.ViewData["ClusterStatuses"] =
                        PrimitiveTypes.GetClusterStatusWithIDs(uniqueClusterStatuses.Distinct());
                }
            });

            return this.View(view);
        }

        /// <summary>
        ///     The matchmaking search.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult MatchmakingSearch()
        {
            this.Session["CurrentSubMenuSelection"] = "Matchmaking";
            this.ViewData["Profiles"] = PrimitiveTypes.GetProfiles();
            this.ViewData["Locations"] = PrimitiveTypes.GetLocations();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["Funds"] = PrimitiveTypes.GetFunds();
            this.ViewData["MatchmakingPartnerTypes"] = PrimitiveTypes.GetMatchmakingPartnerTypes();

            return this.View();
        }

        /// <summary>
        /// The matchmaking search result.
        /// </summary>
        /// <param name="defaultFields">
        /// The default fields.
        /// </param>
        /// <param name="location">
        /// The location.
        /// </param>
        /// <param name="funds">
        /// The funds.
        /// </param>
        /// <param name="matchmakingPartnerType">
        /// The matchmaking partner type.
        /// </param>
        /// <returns>
        /// The <see cref="ActionResult"/>.
        /// </returns>
        [HttpPost]
        public ActionResult MatchmakingSearchResult(
            DefaultSearchFields defaultFields,
            Guid? location,
            string remoteArea,
            string entrepeneur,
            List<Guid> funds,
            List<Guid> profiles,
            Guid? matchmakingPartnerType)
        {
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            if (location.HasValue && location.Value == Guid.Empty)
            {
                location = null;
            }

            this.ViewData["Profiles"] = PrimitiveTypes.GetProfiles();
            this.ViewData["CriteriaLocation"] = location;
            this.ViewData["CriteriaFunds"] = funds ?? new List<Guid>();
            this.ViewData["DefaultFields"] = defaultFields;
            this.ViewData["Partners"] = PrimitiveTypes.GetMatchmakingPartners();
            this.ViewData["CriteriaPartnerType"] = matchmakingPartnerType;
            this.ViewData["PartnerTypes"] = PrimitiveTypes.GetMatchmakingPartnerTypes();
            this.ViewData["Locations"] = PrimitiveTypes.GetLocations();
            this.ViewData["Funds"] = PrimitiveTypes.GetFunds();

            ListView<Matchmaking> view = null;
            List<TableViewHeaderItem> headerItems = MatchmakingController.GetHeaderItems();
            CRUDServiceProvider.WithCRUDService(client =>
            {
                bool ent = entrepeneur == "true" ? true : false;
                bool remote = remoteArea == "true" ? true : false;
                var query = new MatchmakingQuery()
                {
                    ProfilesAreAtRemoteArea = remote,
                    ProfilesAreEntrepreneur = ent,
                    WithPartnerType = matchmakingPartnerType,
                    AtLocation = location,
                    Profiles = (profiles ?? new List<Guid>()).ToArray(),
                    DefaultFields = defaultFields,
                    ContainsFunds = (funds ?? new List<Guid>()).ToArray(),
                    Settings = new SearchSettings()
                };
                var res = client.Query(query) as MatchmakingResult;
                if (res != null)
                {
                    view = new ListView<Matchmaking>(res.List.ToList(), res.TotalRowCount, headerItems);
                }
            });

            return this.View(view);
        }

        /// <summary>
        ///     The networking search.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult NetworkingSearch()
        {
            this.Session["CurrentSubMenuSelection"] = "Networking";
            this.ViewData["Presentations"] = PrimitiveTypes.GetPresentations();
            this.ViewData["Regions"] = PrimitiveTypes.GetRegions();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["Locations"] = PrimitiveTypes.GetLocations();
            this.ViewData["Profiles"] = PrimitiveTypes.GetProfiles();

            return this.View();
        }

        [HttpPost]
        public ActionResult NetworkingSearchResult(
            DefaultSearchFields defaultFields,
            Guid? location,
            string remoteArea,
            string entrepeneur,
            List<Guid> profiles,
            List<Guid> presentations,
            string networkType,
            Guid? organizer,
            List<Guid> supportForBusinessAttendance,
            List<string> Roles
            )
        {
            if (location.HasValue && location.Value == Guid.Empty)
            {
                location = null;
            }
            if (organizer.HasValue && organizer.Value == Guid.Empty)
            {
                organizer = null;
            }

            this.ViewData["CriteriaLocation"] = location;
            this.ViewData["CriteriaNetworkType"] = networkType;
            this.ViewData["CriteriaOrganizer"] = organizer;
            this.ViewData["CriteriaProfiles"] = profiles ?? new List<Guid>();
            this.ViewData["CriteriaPresentations"] = presentations ?? new List<Guid>();
            this.ViewData["CriteriaSupportForBusinessAttendance"] = supportForBusinessAttendance ?? new List<Guid>();
            this.ViewData["DefaultFields"] = defaultFields;

            ListView<Activity> view = null;
            List<TableViewHeaderItem> headerItems = NetworkingController.GetHeaderItems();
            CRUDServiceProvider.WithCRUDService(
                client =>
                {
                    bool ent = entrepeneur == "true" ? true : false;
                    bool remote = remoteArea == "true" ? true : false;
                    var query = new ActivityQuery
                    {
                        HasNetworkActivity = true,
                        Settings = new SearchSettings(),
                        DefaultFields = defaultFields,
                        AtLocation = location,
                        ProfilesAreAtRemoteArea = remote,
                        ProfilesAreEntrepreneur = ent,
                        WithAttendees = (profiles ?? new List<Guid>()).ToArray(),
                        WithOrganizer = organizer,
                        WithPresentations = (presentations ?? new List<Guid>()).ToArray(),
                        WithSupportForBusinessAttendance = (supportForBusinessAttendance ?? new List<Guid>()).ToArray(),
                        IsConferenceEvent = networkType.Equals("IsConferenceEvent", StringComparison.CurrentCultureIgnoreCase),
                        IsDelegationTravel = networkType.Equals("IsDelegationTravel", StringComparison.CurrentCultureIgnoreCase),
                        IsNetworkingEvent = networkType.Equals("IsNetworkingEvent", StringComparison.CurrentCultureIgnoreCase),
                        IsProductLaunch = networkType.Equals("IsProductLaunch", StringComparison.CurrentCultureIgnoreCase)
                    };

                    if (Roles != null && Roles.Any())
                    {
                        if (Roles.Contains("Attendance"))
                        {
                            query.NAAttendance = true;
                        }
                        if (Roles.Contains("Booth"))
                        {
                            query.NABooth = true;
                        }
                        if (Roles.Contains("Organizer"))
                        {
                            query.NAOrganizer = true;
                        }
                    }

                    var res = client.Query(query) as ActivityResult;
                    if (res != null)
                    {
                        view = new ListView<Activity>(res.List.ToList(), res.TotalRowCount, headerItems);

                        var uniqueAttendees = new List<Guid>();
                        foreach (var attendees in res.List.Select(x => x.Attendees))
                        {
                            uniqueAttendees.AddRange(attendees.ToList());
                        }

                        this.ViewData["Presentations"] = PrimitiveTypes.GetPresentations();
                        this.ViewData["Regions"] = PrimitiveTypes.GetRegions();
                        this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
                        this.ViewData["Locations"] = PrimitiveTypes.GetLocations();
                        this.ViewData["Profiles"] = PrimitiveTypes.GetProfiles();
                        this.ViewData["Users"] =
                            PrimitiveTypes.GetUsersWithIDs(
                                res.List.Where(x => x.Creator.HasValue).Select(x => x.Creator.Value));
                    }
                });

            return View(view);
        }

        /// <summary>
        ///     The projects search.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult ProjectsSearch()
        {
            this.Session["CurrentSubMenuSelection"] = "Projects";
            this.ViewData["Locations"] = PrimitiveTypes.GetLocations();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["ProjectMeetingTypes"] = PrimitiveTypes.GetProjectTypes();
            this.ViewData["ProjectMeetingDemonstrations"] = PrimitiveTypes.GetDemonstrations();
            this.ViewData["ProjectMeetingRoles"] = PrimitiveTypes.GetRoles();
            this.ViewData["Profiles"] = PrimitiveTypes.GetProfiles();

            return this.View();
        }

        /// <summary>
        ///     The projects search result.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        [HttpPost]
        public ActionResult ProjectsSearchResult(
            DefaultSearchFields defaultFields,
            Guid? location,
            Guid? projectType,
            Guid? demonstration,
            Guid? role,
            string remoteArea,
            string entrepeneur,
            List<Guid> profiles,
            ProjectMeetingStatusType? statusType
            )
        {
            this.ViewData["DefaultFields"] = defaultFields;
            this.ViewData["CriteriaLocation"] = location;
            this.ViewData["CriteriaProjectType"] = projectType;
            this.ViewData["CriteriaProjectDemonstration"] = demonstration;
            this.ViewData["CriteriaProjectRole"] = role;
            this.ViewData["CriteriaStatusType"] = statusType;
            this.ViewData["Profiles"] = PrimitiveTypes.GetProfiles();
            this.ViewData["Locations"] = PrimitiveTypes.GetLocations();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["ProjectMeetingTypes"] = PrimitiveTypes.GetProjectTypes();
            this.ViewData["ProjectMeetingDemonstrations"] = PrimitiveTypes.GetDemonstrations();
            this.ViewData["ProjectMeetingRoles"] = PrimitiveTypes.GetRoles();

            this.ViewData["Roles"] = PrimitiveTypes.GetRoles();

            ListView<ProjectMeeting> view = null;
            List<TableViewHeaderItem> headerItems = ProjectsController.GetHeaderItems();
            CRUDServiceProvider.WithCRUDService(client =>
            {
                bool ent = entrepeneur == "true" ? true : false;
                bool remote = remoteArea == "true" ? true : false;
                var query = new ProjectMeetingQuery()
                {
                    ProfilesAreAtRemoteArea = remote,
                    ProfilesAreEntrepreneur = ent,
                    WithProjectType = projectType,
                    WithStatus = statusType ?? ProjectMeetingStatusType.None,
                    WithDemonstration = demonstration,
                    Profiles = (profiles ?? new List<Guid>()).ToArray(),
                    WithRole = role,
                    AtLocation = location,
                    DefaultFields = defaultFields,
                    Settings = new SearchSettings()
                };
                var res = client.Query(query) as ProjectMeetingResult;
                if (res != null)
                {
                    view = new ListView<ProjectMeeting>(res.List.ToList(), res.TotalRowCount, headerItems);
                }
            });

            return this.View(view);
        }




        /// <summary>
        ///     The newsinformation search.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        public ActionResult NewsInformationSearch()
        {
            this.Session["CurrentSubMenuSelection"] = "NewsInformation";
            this.ViewData["Funds"] = PrimitiveTypes.GetFunds();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["Types"] = PrimitiveTypes.GetNewsInformationTypes();
            return this.View();
        }

        /// <summary>
        ///     The newsinformation search.
        /// </summary>
        /// <returns>
        ///     The <see cref="ActionResult" />.
        /// </returns>
        [HttpPost]
        public ActionResult NewsInformationSearchResult(
            DefaultSearchFields defaultFields,
            Guid? type,
            List<Guid> funds
            )
        {
            this.ViewData["DefaultFields"] = defaultFields;
            this.ViewData["CriteriaType"] = type;
            this.ViewData["CriteriaFunds"] = funds ?? new List<Guid>();

            this.ViewData["Funds"] = PrimitiveTypes.GetFunds();
            this.ViewData["Projects"] = PrimitiveTypes.GetProjects();
            this.ViewData["Types"] = PrimitiveTypes.GetNewsInformationTypes();

            ListView<NewsInformation> view = null;
            List<TableViewHeaderItem> headerItems = NewsInformationController.GetHeaderItems();
            CRUDServiceProvider.WithCRUDService(client =>
            {
                var query = new NewsInformationQuery()
                {
                    WithFunds = (funds ?? new List<Guid>()).ToArray(),
                    WithType = type,
                    DefaultFields = defaultFields,
                    Settings = new SearchSettings()
                };
                var res = client.Query(query) as NewsInformationResult;
                if (res != null)
                {
                    view = new ListView<NewsInformation>(res.List.ToList(), res.TotalRowCount, headerItems);
                }
            });

            return this.View(view);
        }

        #endregion
    }
}